#!/usr/bin/env python
#-*- coding:utf-8 -*
#
# Kontrolcu
#  - LibKontrolcu icin konsol uygulaması
#
# Geliştiriciler:
#  - Osman KARAGÖZ <osmank3@gmail.com>
#  - Taha Doğan Güneş <tdgunes@gmail.com>
# Belgelendirici:
#  - Okan Okuroğulları <ookurogullari@gmail.com>
#
# Web Sitesi: http://code.google.com/p/kontrolcu
# Lisansı: GPL v3 ile lisanslanmıştır.
#
# Yardım dökümanlarını http://code.google.com/p/kontrolcu/w/list 
#                                     adresinden bulabilirsiniz.
_surum = "1.6"

import sys, hashlib, os
from optparse import OptionParser, OptionGroup

try:
    import libkontrolcu
except:
    print "libkontrolcu modülü bulunamadı!"
veri = []
sonveri = []

def kontroltipi(tip):
    global kontip, KonTipUzan
    if tip == "md5":
        kontip=hashlib.md5
        KonTipUzan = ".md5sum"
    elif tip == "sha1":
        kontip=hashlib.sha1
        KonTipUzan = ".sha1sum"
    elif tip == "sha224":
        kontip=hashlib.sha224
        KonTipUzan = ".sha224sum"
    elif tip == "sha256":
        kontip=hashlib.sha256
        KonTipUzan = ".sha256sum"
    elif tip == "sha384":
        kontip=hashlib.sha384
        KonTipUzan = ".sha384sum"
    elif tip == "sha512":
        kontip=hashlib.sha512
        KonTipUzan = ".sha512sum"


def toplamalma(liste, yaz=True):
    global ciktiliste
    ciktiliste=[]
    sonuc=[]
    for n in liste:
        try:
            libkontrolcu.toplamver(kontip, n) #toplamları isteme
            sonuc.append(libkontrolcu.toplam)
        except IOError:
            sonuc.append("Dosya bulunamadı:")
        except MemoryError:
            sonuc.append("Geçici belleğe sığmıyor:")
    for n in range(len(sonuc)):
        cikti = sonuc[n] + "  " + liste[n].split("/")[-1]
        if yaz == True:
            print cikti
        if sonuc[n] == "Geçici belleğe sığmıyor:":
            pass
        else:
            ciktiliste.append(cikti)

def dosyakayit(liste):
    if len(ciktiliste) == 1:
        dosyadi = liste[0]
        dosya = dosyadi + KonTipUzan
        try:
            kayit = open(dosya, "w")
            kayit.write(ciktiliste[0])
            kayit.write("\n")
            print dosya.split("/")[-1], "başarıyla kaydedildi."
        except IOError, (hata_no, hata):
            if hata_no == 13:
                print "Dosya Kaydedilemedi! Yazma izninizi kontrol edin!"
    if len(ciktiliste) > 1:
        soru = raw_input("Kayıt için dosya adı giriniz : ")
        dosya = soru + KonTipUzan
        try:
            kayit = open(dosya, "w")
            for i in ciktiliste:
                kayit.write(i)
                kayit.write("\n")
            print dosya, "başarıyla kaydedildi."
        except IOError, (hata_no, hata):
            if hata_no == 13:
                print "Dosya Kaydedilemedi! Yazma izninizi kontrol edin!\n(Yazma izni için su,sudo gibi komutlar kullanabilirsiniz.)"

def num():
    a=os.listdir("./")
    a.sort()
    n=1
    numara={}
    for dosya in a:
        if os.path.isfile(dosya) == 1:
            numara[n] = dosya
            print n, "->", numara[n]
            n += 1
        else:
            pass
    secilen=raw_input("Seçtiklerinizi aralarında boşluk bırakarak yazın:\n")
    listesec=secilen.split()
    global liste
    liste=[]
    for m in listesec:
        try:
            liste.append(numara[int(m)])
        except KeyError:
            print "Listeden sayı seçmelisiniz."
            exit()

def kontrolet(liste):
    if liste[0][:5] == "http:" or liste[0][:4] == "ftp:" or liste[0][:6] == "https:":
        if len(liste) == 1:
            yol = raw_input("Dosyanın bulunduğu yolu girin (Bu dizin için ./ kullanın): ")
            liste.append(yol)
        else:
            pass
    try:
        libkontrolcu.check(liste)
        if len(libkontrolcu.hatadurum) > 0:
            if 001 in libkontrolcu.hatadurum:
                print "Adresteki dosya, kontrol toplamı dosyası değil!"
            elif 002 in libkontrolcu.hatadurum:
                print "Kontrol toplamı dosyası hatalı!"
            elif 003 in libkontrolcu.hatadurum:
                print libkontrolcu.hatadurum[libkontrolcu.hatadurum.index(003)+1], " dosyası bulunamıyor."
            elif 004 in libkontrolcu.hatadurum:
                print libkontrolcu.hatadurum[libkontrolcu.hatadurum.index(004)+1], " dosyası geçici belleğe sığmıyor."
        elif len(libkontrolcu.hatadurum) == 0:
            n=0
            while len(libkontrolcu.sondurum) > n:
                if libkontrolcu.sondurum[n] == True:
                    print libkontrolcu.sondurum[n+1] + " eskisi ile uyuşuyor"
                elif libkontrolcu.sondurum[n] == False:
                    print libkontrolcu.sondurum[n+1] + " değişmiş."
                n += 2
    except IOError, (hata_no, hata):
        if hata_no == 2:
            print "%s dosyası bulunamıyor!"% liste[0]
        if hata_no == "socket error":
            print "Adres bulunamıyor!"

def saglamayap(liste):
    n=0
    while len(liste) > n:
        try:
            libkontrolcu.ccheck(liste[n], liste[n+1])
            n += 2
        except IOError, (hata_no, hata):
            if hata_no == 2:
                print "Dosya %s bulunamadı."% liste[n]
                exit()
        except MemoryError:
            print "Dosya %s geçici belleğe sığmıyor."% liste[n]
    if len(libkontrolcu.hatadurum) > 0:
        if 011 in libkontrolcu.hatadurum:
            print "Kontrol toplamı hatalı!"
    elif len(libkontrolcu.hatadurum) == 0:
        n=0
        while len(libkontrolcu.sondurum) > n:
            if libkontrolcu.sondurum[n] == True:
                print libkontrolcu.sondurum[n+1] + " eskisi ile uyuşuyor"
            elif libkontrolcu.sondurum[n] == False:
                print libkontrolcu.sondurum[n+1] + " değişmiş."
            n += 2

def ServMenu(durum):
    if durum == True:
        dosya=open("/usr/kde/4/share/kde4/services/ServiceMenus/kontrolcu.desktop", "w")
        dosya.write("[Desktop Entry]\nEncoding=UTF8\nType=Service\nX-KDE-Submenu=Kontrolcu\nX-KDE-Submenu[tr]=Kontrolcu\nX-KDE-ServiceTypes=KonqPopupMenu/Plugin,all/allfiles\nActions=md5;sha1;sha224;sha256;sha384;sha512\nAuthor=tdgunes\n\n[Desktop Action md5]\nType=Application\nName=Check with md5\nName[tr]=md5'le kontrol\nExec=kontrolcu --tip=md5 -k %f\n\n\n[Desktop Action sha1]\nType=Application\nName=Check with sha1\nName[tr]=sha1'le kontrol\nExec=kontrolcu --tip=sha1 -k %f\n\n\n[Desktop Action sha224]\nType=Application\nName=Check with sha224\nName[tr]=sha224'le kontrol\nExec=kontrolcu --tip=sha224 -k %f\n\n\n[Desktop Action sha256]\nType=Application\nName=Check with sha256\nName[tr]=sha256'le kontrol\nExec=kontrolcu --tip=sha256 -k %f\n\n\n[Desktop Action sha384]\nType=Application\nName=Check with sha384\nName[tr]=sha384'le kontrol\nExec=kontrolcu --tip=sha384 -k %f\n\n\n[Desktop Action sha512]\nType=Application\nName=Check with sha512\nName[tr]=sha512'le kontrol\nExec=kontrolcu --tip=sha512 -k %f")
        dosya.close()
        print "Servis menüsü açıldı."
    elif durum == False:
        try:
            os.remove("/usr/kde/4/share/kde4/services/ServiceMenus/kontrolcu.desktop")
            print "Servis menüsü kapatıldı."
        except:
            pass

def ana():
    menu=OptionParser(usage="\nkontrolcu -t [tip] [dosyalar]\nkontrolcu -k -t [tip] [dosyalar]\nkontrolcu -s [kontrol toplamı] [dosya]\nkontrolcu --kontrol [kontrol dosyası]\nkontrolcu -n [ekleri]\n\nkontrolcu -g [qt ya da tk]\nkontrolcu --servmenuac\nkontrolcu --servmenukapat", description="Kontrolcu, dosyaların kontrol toplamlarını alan bir programdır.", version="kontrolcu version %s"% _surum)
    menu.add_option("-t", "--tip", dest="tip", help="Kontrol tipleri: md5-sha1-sha224-sha256-sha384-sha512")
    menu.add_option("-n", "--num", action = "store_true", dest="numaralandir", help="Dosya listesini numaralandırarak kolay seçim yapılmasını sağlar. Ekleri: -t -k -c parametreleri")
    menu.add_option("-k", "--kaydet", action="store_true", dest="kaydet", help="Kontrol toplamlarını dosyaya yazar.")
    menu.add_option("-c", "--kontrol", dest="kontroldosyasi", help="Kontrol toplamı dosyalarından kontrol yapar.")
    menu.add_option("-s", "--sagla", dest="kontroltoplami", help="Kontrol toplamı ve dosyayı karşılaştırır.")
    grup=OptionGroup(menu, "Diğer işlemler")
    grup.add_option("-g", "--gui", dest="arayuz", help="Qt ve Tk arayüzlerinden biriyle çalışmayı sağlar.")
    grup.add_option("--servmenuac", action="store_true", dest="servmenudurum", help="Servis menüsünden kontrolü açar.")
    grup.add_option("--servmenukapat", action="store_false", dest="servmenudurum", help="Servis menüsünden kontrolü kapatır.")
    menu.add_option_group(grup)
    (secenek, dosyalar) = menu.parse_args()
    
    

    if secenek.servmenudurum == True or secenek.servmenudurum == False:
        if not os.getuid() == 0:
            print "Bu işlem için yetkili kullanıcı olmalısınız."
        else:
            ServMenu(secenek.servmenudurum)
        
    elif secenek.arayuz:
        if secenek.arayuz == "qt":
            try:
                import kontrolcuQt
                kontrolcuQt.konqt()
            except:
                print "Qt arayüz bulunamıyor!\nPaket yöneticinizden lütfen kontrolcu-qt paketini indirin."
        elif secenek.arayuz == "tk":
            try:
                import kontrolcuTk
                kontrolcuTk.kontk()
            except:
                print "Tkinter arayüz bulunamıyor!\nPaket yöneticinizden lütfen kontrolcu-tk paketini indirin."
                
    elif secenek.numaralandir:
        if secenek.kontroldosyasi:
            num()
            liste.append(os.getcwd())
            kontrolet(liste)
            
        elif secenek.tip:
            kontroltipi(secenek.tip)
            if secenek.kaydet:
                num()
                toplamalma(liste, False)
                dosyakayit(liste)
                
            else:
                num()
                toplamalma(liste)
                
        else:
            menu.error("Geçersiz argüman dizimi!")
            
    elif secenek.kontroldosyasi:
        kontrolet([secenek.kontroldosyasi])

    elif len(dosyalar) == 0:
        menu.error("Lütfen dosya seçiniz.")

    else:            
        if secenek.kontroltoplami:
            saglamaliste=[dosyalar[0], secenek.kontroltoplami]
            saglamayap(saglamaliste)
            
        elif secenek.tip:
            kontroltipi(secenek.tip)
            if secenek.kaydet:
                toplamalma(dosyalar, False) #toplam elde ediliyor.
                dosyakayit(dosyalar)
            
            else:
                toplamalma(dosyalar)
                
        else:
            menu.error("Kontrol tipini giriniz.")
            
if __name__ == "__main__":
    ana()